package com.dji.system.core.nio;

import java.nio.charset.Charset;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dji.bean.Compoment;

@Compoment
public class CharsetCodecFactory implements ProtocolCodecFactory {

	@Override
	public ProtocolDecoder getDecoder(IoSession session) throws Exception {
		return new CharsetDecoder();
	}

	@Override
	public ProtocolEncoder getEncoder(IoSession session) throws Exception {
		return new CharsetEncoder();
	}
}

@Compoment
class CharsetEncoder implements ProtocolEncoder {
	private final static Logger log = LoggerFactory.getLogger(CharsetEncoder.class);
	private final static Charset charset = Charset.forName("UTF-8");

	@Override
	public void dispose(IoSession session) throws Exception {

	}

	@Override
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
		IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
		buff.putString(message.toString(), charset.newEncoder());
		buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());
		buff.flip();
		out.write(buff);
	}
}

@Compoment
class CharsetDecoder implements ProtocolDecoder {
	private final static Logger log = LoggerFactory.getLogger(CharsetDecoder.class);
	private final static Charset charset = Charset.forName("UTF-8");
	private IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);

	@Override
	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		// 如果有消息
		while (in.hasRemaining()) {
			// 判断消息是否是结束符，不同平台的结束符也不一样；
			// windows换行符（\r\n）就认为是一个完整消息的结束符了； UNIX 是\n；MAC 是\r
			byte b = in.get();
			if (b == '\n') {
				buff.flip();
				byte[] bytes = new byte[buff.limit()];
				buff.get(bytes);
				String message = new String(bytes, charset);
				buff = IoBuffer.allocate(100).setAutoExpand(true);
				// 如果结束了，就写入转码后的数据
				out.write(message);
			} else {
				buff.put(b);
			}
		}
	}

	@Override
	public void dispose(IoSession session) throws Exception {
		log.info("#########dispose#########");
		log.info((String) session.getCurrentWriteMessage());
	}

	@Override
	public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
		log.info("#########完成解码#########");
	}
}